home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / sbin_-_Static_Binary_Files / IPFWADM-.{3E < prev    next >
Text File  |  1999-09-17  |  21KB  |  857 lines

  1. #! /bin/bash
  2.  
  3. # This is a wrapper script to simulate ipfwadm 2.3a.  It ain't pretty,
  4. # but it should work (for valid commands).  `-V' is translated to `-W'
  5. # or ignored if a `-W' option is already there, but always warned
  6. # about.
  7.  
  8. # Paul.Russell@rustcorp.com.au, Nov-1997.
  9.  
  10. # This program is free software; you can redistribute it and/or modify
  11. # it under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation; either version 2 of the License, or
  13. # (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program; if not, write to the Free Software
  22. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23. #
  24. # Version: 1.0.1: Fixed -t (no longer de-hexizes).
  25. #
  26. # Version: 1.0.2: Fixed undocumented `-a masq'.
  27. #                 Should be OK now with bash v1.
  28. #                 If we can't find ip_fwnames, call /sbin/ipfwadm-2.3.0
  29. #
  30. # Version: 1.1: Fixed printing counts for accounting chains list.
  31. #        Fixed -A -z and -A -f cases to do all 3 acct. rules.
  32. #
  33. # Version: 1.1.1: Fixed syntax error by escaping ( and ).
  34. #
  35. if [ -n "$DEBUG_IPFWADM" ]; then IPCHAINS=print_ipchains;
  36. else IPCHAINS=/sbin/ipchains;
  37. fi
  38. PROC_FIREWALL_NAMES="/proc/net/ip_fwnames"
  39. SPECIAL_CHAIN="IpFwAdM!"
  40. START_MARK=10000
  41.  
  42. barf()
  43. {
  44.     echo "$@"
  45.     echo
  46.     echo If this command worked with the original ipfwadm 2.3, please
  47.     echo submit a bug report to \`ipchains@rustcorp.com\'.  Note that you
  48.     echo now need to be root, even to list the chains \(complain to Alan Cox\).
  49.     echo
  50.     echo The best way to do this is to submit the output of \`$0 --version\',
  51.     echo the command used to obtain this error, any previous ipfwadm
  52.     echo commands, and the output of \`ipchains-save\'.
  53.     echo
  54.     echo Then try flushing all the rules \`ipchains -F; ipchains -X\',
  55.     echo setting the DEBUG_IPFWADM variable \`export DEBUG_IPFWADM=1\' or
  56.     echo \`setenv DEBUG_IPFWADM 1\' and rerunning the command\(s\) which
  57.     echo caused this error.
  58.     exit 1
  59. }
  60.  
  61. print_ipchains()
  62. {
  63.     echo ipchains "$@" 1>&2
  64.     /sbin/ipchains "$@"
  65. }
  66.  
  67. setup_chains()
  68. {
  69.     if [ `wc -l < $PROC_FIREWALL_NAMES` != 3 -a -z "$DEBUG_IPFWADM" ]
  70.     then
  71.     echo You cannot mix the \`ipfwadm\' wrapper with ipchains. 1>&2
  72.     echo You must delete all user chains and flush all built-in chains 1>&2
  73.     echo if you want to use the \`ipfwadm\' wrapper. 1>&2
  74.     exit 1
  75.     fi
  76.     $IPCHAINS -N acctin
  77.     $IPCHAINS -N acctout
  78.     $IPCHAINS -N acctboth
  79.     $IPCHAINS -N inp
  80.     $IPCHAINS -N out
  81.     $IPCHAINS -N fwd
  82.  
  83.     # Let all fragments through like the old code used to.
  84.     $IPCHAINS -A input -f -j ACCEPT
  85.     $IPCHAINS -A output -f -j ACCEPT
  86.     $IPCHAINS -A forward -f -j ACCEPT
  87.  
  88.     # Jump to accounting rules.  Order of traversal of acct rules
  89.     # doesn't matter.
  90.     $IPCHAINS -A input -j acctin
  91.     $IPCHAINS -A input -j acctboth
  92.     $IPCHAINS -A output -j acctout
  93.     $IPCHAINS -A output -j acctboth
  94.  
  95.     # Now go to `real' chains.
  96.     $IPCHAINS -A input -j inp
  97.     $IPCHAINS -A output -j out
  98.     $IPCHAINS -A forward -j fwd
  99.  
  100.     # Create dummy chains to mark this as an ipfwadm-emulation firewall.
  101.     $IPCHAINS -N $SPECIAL_CHAIN
  102.     # Insert min and max mark values.
  103.     $IPCHAINS -A $SPECIAL_CHAIN -m $START_MARK
  104.     $IPCHAINS -A $SPECIAL_CHAIN -m $(($START_MARK + 1))
  105. }
  106.  
  107. # SIGH.  We use identical marks to indicate which rules are actually
  108. # the same rule (to simulate multiple ports, and -y without -P tcp).
  109.  
  110. # We start the marks at 1,000,000, so we can insert before them or append
  111. # after them.
  112.  
  113. # In the accounting chain, marks are unique between the three acct* chains,
  114. # so we can tell ordering.
  115.  
  116. print_count()
  117. {
  118.     count=$(($1))
  119.     if let $(($count > 99999))
  120.     then
  121.     cntkb=$((($count + 500) / 1000))
  122.     if let $((cntkb > 9999))
  123.     then
  124.         cntmb=$((($count + 500000) / 1000000))
  125.         printf "%4sM " $cntmb
  126.     else
  127.         printf "%4sK " $cntkb
  128.     fi
  129.     else
  130.     printf "%5s " $count
  131.     fi
  132. }
  133.  
  134. dump_rule()
  135. {
  136. # ARGS: $LIST_VERBOSE $EXPAND_NUMBERS $BIDIR $SYN_NO_PROTO $SRCPORTS $DSTPTS
  137. # $PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX $IFNM $NUM $SRCIP $DSTIP $REDIR
  138. # $PRINT_COUNTS
  139.  
  140. # The ipfwadm code looks like: (* = -e only)
  141. # *    *               *    *    *    *    *       
  142. # pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR
  143.     if [ -n "$1" -o -n "${19}" ]
  144.     then
  145.     # Packet and byte counts.
  146.     if [ -n "$2" ]; then printf "%8u " $7; else print_count $7; fi
  147.     if [ -n "$2" ]; then printf "%8u " $8; else print_count $8; fi
  148.     fi
  149.  
  150.     # Kind
  151.     case "$9" in
  152.     in) printf "%-3s " "$9" ;;
  153.     out) printf "%-3s " "$9" ;;
  154.     i/o) printf "%-3s " "$9" ;;
  155.     *) printf "%-5s " "$9" ;;
  156.     esac
  157.  
  158.     # Proto
  159.     printf "%-5s" "${10}"
  160.  
  161.     if [ -n "$1" ]
  162.     then
  163.     # Flags
  164.     if [ "$3" != 0 ]; then printf "b"; else printf "-"; fi
  165.     case "${11}" in
  166.         *!y*) printf "k-" ;;
  167.         *y*) printf "-y" ;;
  168.         *) printf "--" ;;
  169.     esac
  170.     case "${11}" in
  171.         *l*) printf "l " ;;
  172.         *) printf "- " ;;
  173.     esac
  174.  
  175.     # TOS
  176.     printf "${12} ${13} "
  177.  
  178.     # Interface name
  179.     printf "%-7.16s " "${14}"
  180.  
  181.     # Interface address
  182.     if [ -n "${15}" ]; then printf "%-15s " 0.0.0.0;
  183.     else printf "%-15s " any;
  184.     fi
  185.     fi
  186.  
  187.     # Source and dest.
  188.     printf "%-20s " "${16}"
  189.     printf "%-20s" "${17}"
  190.  
  191.     # Source Ports.
  192.     if [ "${10}" != tcp -a "${10}" != udp -a "${10}" != icmp ]
  193.     then
  194.     echo " n/a"
  195.     return
  196.     fi
  197.     printf " "
  198.     printf "$5" | tr ' ' ','
  199.  
  200.     if [ "${10}" = icmp ]
  201.     then
  202.     echo
  203.     return
  204.     fi
  205.  
  206.     # Dest ports.
  207.     if [ "$5" != "n/a" ]
  208.     then
  209.     printf " -> " 
  210.     printf "$6" | tr ' ' ','
  211.     fi
  212.  
  213.     # redirect ports.
  214.     if [ "$9" = "acc/r" ]
  215.     then
  216.     printf " => %s" "${18}"
  217.     fi
  218.     echo
  219. }
  220.  
  221. get_policy() # CHAIN
  222. {
  223.     case "`ipchains -L $1 | head -1`" in
  224.     *ACCEPT*)
  225.     echo accept;;
  226.     *MASQ*)
  227.     echo accept/masquerade;;
  228.     *REJECT*)
  229.     echo reject;;
  230.     *DENY*)
  231.     echo deny;;
  232.     *)
  233.     barf "Unknown policy for \`$1' - `ipchains -L $1 2>&1`"
  234.     esac
  235. }
  236.  
  237. list_chain() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS
  238. {
  239. # if (!(format & FMT_NOCOUNTS)) {
  240. #     if (format & FMT_KILOMEGA) {
  241. #         fprintf(fp, FMT("%5s ","%s "), "pkts");
  242. #         fprintf(fp, FMT("%5s ","%s "), "bytes");
  243. #     } else {
  244. #         fprintf(fp, FMT("%8s ","%s "), "pkts");
  245. #         fprintf(fp, FMT("%10s ","%s "), "bytes");
  246. #     }
  247. # }
  248.     IS_ACCT=""
  249.     case "$1" in
  250.     acct*) IS_ACCT="Y";;
  251.     inp) printf "IP firewall input rules, default policy: " 
  252.     get_policy input
  253.     ;;
  254.     out) printf "IP firewall output rules, default policy: " 
  255.     get_policy output
  256.     ;;
  257.     fwd) printf "IP firewall forward rules, default policy: " 
  258.     get_policy forward
  259.     ;;
  260.     *) barf "Unknown chain for list_chain - \`$1'"
  261.     ;;
  262.     esac
  263.  
  264.     if [ -n "$2" -o -n "$IS_ACCT" ]
  265.     then
  266.     if [ -z "$4" ]
  267.     then
  268.         printf "%5s " pkts
  269.         printf "%5s " bytes
  270.     else
  271.         printf "%8s " pkts
  272.         printf "%10s " bytes
  273.     fi
  274.     fi
  275.  
  276. # if (!(format & FMT_NOKIND)) {
  277. #     if (chain == CHN_ACCT)
  278. #         fprintf(fp, FMT("%-3s ","%s "), "dir");
  279. #     else
  280. #         fprintf(fp, FMT("%-5s ","%s "), "type");
  281. # }
  282.     case "$1" in
  283.     acct*) printf "%-3s " dir ;;
  284.     *) printf "%-5s " type ;;
  285.     esac
  286.  
  287. # fputs("prot ", fp);
  288.     printf "prot "
  289.  
  290. # if (format & FMT_OPTIONS)
  291. #     fputs("opt  ", fp);
  292. # if (format & FMT_TOS)
  293. #     fputs("tosa tosx ", fp);
  294. # if (format & FMT_VIA) {
  295. #     fprintf(fp, FMT("%-7s ","(%s "), "ifname");
  296. #     fprintf(fp, FMT("%-15s ","%s) "), "ifaddress");
  297. # }
  298.     if [ -n "$2" ]
  299.     then
  300.     printf "opt  tosa tosx %-7s %-15s " ifname ifaddress
  301.     fi
  302.  
  303. # fprintf(fp, FMT("%-20s ","%s "), "source");
  304. # fprintf(fp, FMT("%-20s ","%s "), "destination");
  305. # fputs("ports\n", fp);
  306. # }
  307.     printf "%-20s %-20s ports" source destination
  308.     echo
  309.  
  310.     case "$1" in
  311.     acct*) shift;
  312.         (list_chain_real acctin "$@" "1" "1"
  313.          list_chain_real acctout "$@" "1" "1" 
  314.          list_chain_real acctboth "$@" "1" "1") | sort -n | cut -c11-;;
  315.     *) list_chain_real "$@" ;;
  316.     esac
  317. }
  318.  
  319. list_chain_real() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS $PRINT_COUNTS $PREPEND_MARK
  320. {
  321.     CHAIN="$1"
  322.     LIST_VERBOSE="$2"
  323.     NUMERIC="$3"
  324.     EXPAND_NUMBERS="$4"
  325.     PRINT_COUNTS="$5"
  326.     PREPEND_MARK="$6"
  327.  
  328.     # The ipfwadm code looks like: (* = -e only)
  329.     # *    *               *    *    *    *    *       
  330.     # pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR
  331.     #
  332.     # The ipchains code looks like: (* = -v only)
  333.     # *    *               *    *    *    *    *       
  334.     # pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
  335.     LAST_MARK=xxx
  336.  
  337.     BIDIR=0
  338.     SYN_NO_PROTO=0
  339.     SRCPORTS=""
  340.     DSTPORTS=""
  341.  
  342.     [ -z "$NUMERIC" ] || NUMERIC="-n"
  343.     $IPCHAINS -L $CHAIN -v -x $NUMERIC | tail +3 |
  344.     while true
  345.     do
  346.     if ! read PCNT BCNT TARG PROTO FLAGS TOSA TOSX IFNM MARK SRCIP DSTIP SRCPTS IGN1 DSTPTS REDIR
  347.     then
  348.         # Dump last rule.
  349.         if [ "$LAST_MARK" != "xxx" ] 
  350.         then
  351.         [ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK"
  352.         dump_rule "$LIST_VERBOSE" "$EXPAND_NUMBERS" $BIDIR $SYN_NO_PROTO "$SRCPORTS" "$DSTPORTS" $LAST_PCNT $LAST_BCNT $LAST_TARG $LAST_PROTO $LAST_FLAGS $LAST_TOSA $LAST_TOSX "$LAST_IFNM" "$NUMERIC" $LAST_SRCIP $LAST_DSTIP "$LAST_REDIR" "$PRINT_COUNTS"
  353.         fi
  354.         return
  355.     fi
  356.     [ -z "$DEBUG_IPFWADM" ] || echo RULE is "$PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX "$IFNM" $MARK $SRCIP $DSTIP $SRCPTS $IGN1 $DSTPTS $REDIR" 1>&2
  357.  
  358.     if [ "$LAST_MARK" = "$MARK" ]
  359.     then
  360. # Fold rules back together.
  361.     
  362. # We combine for any of the following reasons:
  363. # -k or -y used with no protocol: first rule has proto TCP and 'y'.
  364. # -b used: SRC & DST reversed.
  365. # Multiple ports: all the same but for port.
  366.  
  367. # Worst cases:
  368. # ipfwadm -I -a accept -b -P tcp -S 0/0 1 4 -D 1/1 5 9
  369. # => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
  370. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 1       5
  371. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 5       1
  372. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 1       9
  373. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 9       1
  374. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 4       5
  375. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 5       4
  376. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 4       9
  377. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 9       4
  378. #
  379. # ipfwadm -I -a accept -b -y -S 0/0 -D 1/1
  380. # => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
  381. #    ?    ?    ?    TCP   ?y?? ?    ?    ?    ?    0/0 1/1
  382. #    ?    ?    ?    TCP   ?y?? ?    ?    ?    ?    1/1 0/0
  383. #    ?    ?    ?    ANY   ?-?? ?    ?    ?    ?    0/0 1/1
  384. #    ?    ?    ?    ANY   ?-?? ?    ?    ?    ?    1/1 0/0
  385. #         if [ -n "$DEBUG_IPFWADM" ]
  386. #         then
  387. #        echo LAST_PROTO = \`"$LAST_PROTO"\'
  388. #        echo PROTO = \`"$PROTO"\'
  389. #         echo LAST_SRCIP = \`"$LAST_SRCIP"\'
  390. #         echo DSTIP = \`"$DSTIP"\'
  391. #         echo LAST_DSTIP = \`"$LAST_DSTIP"\'
  392. #         echo SRCIP = \`"$SRCIP"\'
  393. #         echo LAST_SRCPTS = \`"$LAST_SRCPTS"\'
  394. #         echo DSTPTS = \`"$DSTPTS"\'
  395. #         echo LAST_DSTPTS = \`"$LAST_DSTPTS"\'
  396. #         echo SRCPTS = \`"$SRCPTS"\'
  397. #         fi
  398.         if [ "$LAST_PROTO" = \!tcp -a "$PROTO" = tcp ]
  399.         then
  400.         [ -n "$DEBUG_IPFWADM" ] && echo "Found SYN rule."
  401.         SYN_NO_PROTO=1
  402.         PCNT=$(($LAST_PCNT + $PCNT))
  403.         BCNT=$(($LAST_BCNT + $BCNT))
  404.         PROTO="all"
  405.         elif [ "$LAST_SRCIP" = "$DSTIP" -a "$LAST_DSTIP" = "$SRCIP" -a "$LAST_SRCPTS" = "$DSTPTS" -a "$LAST_DSTPTS" = "$SRCPTS" ]
  406.         then
  407.         [ -n "$DEBUG_IPFWADM" ] && echo "Found bidir rule."
  408.         BIDIR=1
  409.         LAST_PCNT=$(($LAST_PCNT + $PCNT))
  410.         LAST_BCNT=$(($LAST_BCNT + $BCNT))
  411.         # Don't transfer this rule to LAST_ vars - effectively ignore.
  412.         continue;
  413.         else
  414.         [ -n "$DEBUG_IPFWADM" ] && echo "Found port rule."
  415.         # For n source ports and m dest ports, there will be
  416.         # n x m rules.  So, we add to SRCPORTS when we see a new
  417.         # SRCPTS, but only add to DSTPORTS for the first SRCPORTS.
  418.         if [ "$SRCPTS" != "$LAST_SRCPTS" ]
  419.         then
  420.             SRCPORTS="$SRCPORTS $SRCPTS"
  421.         fi
  422.         if [ "$SRCPORTS" = "$SRCPTS" ]
  423.         then
  424.             DSTPORTS="$DSTPORTS $DSTPTS"
  425.         fi
  426.         PCNT=$(($LAST_PCNT + $PCNT))
  427.         BCNT=$(($LAST_BCNT + $BCNT))
  428.         fi
  429.     else
  430.         # Dump last rule.
  431.         if [ "$LAST_MARK" != "xxx" ]
  432.         then
  433.         [ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK"
  434.         dump_rule "$LIST_VERBOSE" "$EXPAND_NUMBERS" $BIDIR $SYN_NO_PROTO "$SRCPORTS" "$DSTPORTS" $LAST_PCNT $LAST_BCNT $LAST_TARG $LAST_PROTO $LAST_FLAGS $LAST_TOSA $LAST_TOSX "$LAST_IFNM" "$NUMERIC" $LAST_SRCIP $LAST_DSTIP "$LAST_REDIR" "$PRINT_COUNTS"
  435.         fi
  436.  
  437.         BIDIR=0
  438.         SYN_NO_PROTO=0
  439.         SRCPORTS="$SRCPTS"
  440.         DSTPORTS="$DSTPTS"
  441.     fi
  442.  
  443.     # Save for next iteration, in case mark the same.
  444.     LAST_PCNT=$PCNT
  445.     LAST_BCNT=$BCNT
  446.     LAST_PROTO=$PROTO
  447.     LAST_FLAGS=$FLAGS
  448.     LAST_TOSA=$TOSA
  449.     LAST_TOSX=$TOSX
  450.     LAST_IFNM="$IFNM"
  451.     LAST_MARK=$MARK
  452.     LAST_SRCIP=$SRCIP
  453.     LAST_DSTIP=$DSTIP
  454.     LAST_REDIR="$REDIR"
  455.     LAST_SRCPTS="$SRCPTS"
  456.     LAST_DSTPTS="$DSTPTS"
  457.     case "$CHAIN" in
  458.     acctin) LAST_TARG=in ;;
  459.     acctout) LAST_TARG=out ;;
  460.     acctboth) LAST_TART=i/o ;;
  461.     *)
  462.         case "$TARG" in
  463.         REDIRECT) LAST_TARG="acc/r" ;;
  464.         MASQ) LAST_TARG="acc/m" ;;
  465.         ACCEPT) LAST_TARG="acc" ;;
  466.         REJECT) LAST_TARG="rej" ;;
  467.         DENY) LAST_TARG="deny" ;;
  468.         *) barf Unknown target \`"$TARG"\'. ;;
  469.         esac
  470.         ;;
  471.     esac
  472.     done
  473. }
  474.  
  475. ############################################################################
  476.  
  477. if [ ! -f $PROC_FIREWALL_NAMES ]
  478. then
  479.     if [ -f /proc/net/ip_input -a -x /sbin/ipfwadm-2.3.0 ]
  480.     then
  481.     # Old kernel.  Let's play nice.
  482.     exec /sbin/ipfwadm-2.3.0 "$@" 
  483.     fi
  484.     echo "Generic IP Firewall Chains not in this kernel" 1>&2
  485.     exit 1
  486. fi
  487.  
  488. while [ $# != 0 ]
  489. do
  490.     case "$1" in
  491.     -A)
  492.     case x"$2" in
  493.     x-*) CHAIN=acctboth ;;
  494.     xboth) CHAIN=acctboth; shift ;;
  495.     xin) CHAIN=acctin; shift ;;
  496.     xout) CHAIN=acctout; shift ;;
  497.     x) CHAIN=acctboth ;;
  498.      *) barf Unknown option \`"$2"\' ;;
  499.     esac
  500.     ;;
  501.     -I)
  502.     CHAIN=inp
  503.     ;;
  504.     -O)
  505.     CHAIN=out
  506.     ;;
  507.     -F)
  508.     CHAIN=fwd
  509.     ;;
  510.     -M)
  511.     MASQ_MODE=1
  512.     ;;
  513.     -a)
  514.     COMMAND=-A
  515.     case x"$2" in
  516.     x-*) TARGET="" ;;
  517.     x) TARGET="" ;;
  518.     xr*) TARGET=REJECT; shift ;;
  519.     xd*) TARGET=DENY; shift ;;
  520.     xa*) TARGET=ACCEPT; shift ;;
  521.     xm*) TARGET=ACCEPT; MASQ=1; shift ;;
  522.      *) barf Unknown policy for append: \`"$2"\' ;;
  523.     esac
  524.     ;;
  525.     -i)
  526.     COMMAND="-I "
  527.     case x"$2" in
  528.     x-*) TARGET="" ;;
  529.     x) TARGET="" ;;
  530.     xr*) TARGET=REJECT; shift ;;
  531.     xd*) TARGET=DENY; shift ;;
  532.     xa*) TARGET=ACCEPT; shift ;;
  533.      *) barf Unknown policy for insert: \`"$2"\' ;;
  534.     esac
  535.     ;;
  536.     -d)
  537.     COMMAND=-D
  538.     case x"$2" in
  539.     x-*) TARGET="" ;;
  540.     x) TARGET="" ;;
  541.     xr*) TARGET=REJECT; shift ;;
  542.     xd*) TARGET=DENY; shift ;;
  543.     xa*) TARGET=ACCEPT; shift ;;
  544.      *) barf Unknown policy for delete: \`"$2"\' ;;
  545.     esac
  546.     ;;
  547.     -l)
  548.     LIST=1
  549.     ;;
  550.     -z)
  551.     COMMAND=-Z
  552.     ;;
  553.     -f)
  554.     COMMAND=-F
  555.     ;;
  556.     -p)
  557.     COMMAND=-P
  558.     case "$2" in
  559.     r*) TARGET=REJECT; shift ;;
  560.     d*) TARGET=DENY; shift ;;
  561.     a*) TARGET=ACCEPT; shift ;;
  562.      *) barf Unknown policy for -p: \`"$2"\' ;;
  563.     esac
  564.     ;;
  565.  
  566.     -s)
  567.     COMMAND=-S
  568.     OPTIONS="$2 $3 $4"
  569.     shift 3
  570.     ;;
  571.     -c)
  572.     COMMAND=-C
  573.     ;;
  574.     -h)
  575.     print_help
  576.     ;;
  577.     -P)
  578.     PROTOCOL="-p $2"
  579.     shift
  580.     ;;
  581.     -S)
  582.     SRC_OPTIONS="-s $2"
  583.     shift
  584.     while true
  585.     do
  586.         case x"$2" in
  587.         x) break ;;
  588.         x-*) break ;;
  589.         x?*) SRC_PORTS="$2 $SRC_PORTS" ;;
  590.         esac
  591.         shift
  592.     done
  593.     ;;
  594.     -D)
  595.     DST_OPTIONS="-d $2"
  596.     shift
  597.     while true
  598.     do
  599.         case x"$2" in
  600.         x) break ;;
  601.         x-*) break ;;
  602.         x?*) DST_PORTS="$2 $DST_PORTS" ;;
  603.         esac
  604.         shift
  605.     done
  606.     ;;
  607.     -V)
  608.     VIA_ADDR="$2"
  609.     shift
  610.     ;;
  611.     -W)
  612.     INTERFACE="$2"
  613.     OPTIONS="$OPTIONS -i $2"
  614.     shift
  615.     ;;
  616.     -b)
  617.     OPTIONS="$OPTIONS -b"
  618.     ;;
  619.     -e)
  620.     LIST_VERBOSE=1
  621.     ;;
  622.     -k)
  623.     TCPSYN="! -y"
  624.     ;;
  625.     -m)
  626.     MASQ=1
  627.     ;;
  628.     -n)
  629.     NUMERIC=1
  630.     ;;
  631.     -o)
  632.     OPTIONS="$OPTIONS -l"
  633.     ;;
  634.     -r)
  635.     case x"$2" in
  636.         x-*) REDIR=0 ;;
  637.         x) REDIR=0 ;;
  638.         x?*) REDIR="$2"; shift ;;
  639.     esac
  640.     ;;
  641.     -t)
  642.     TOSAND=$(($2 | 0x01))
  643.     TOSXOR=$(($3 & 0xFE))
  644.     OPTIONS="$OPTIONS -t "`printf "0x%02x 0x%02x" $TOSAND $TOSXOR`
  645.     shift 2
  646.     ;;
  647.     -v)
  648.     OPTIONS="$OPTIONS -v"
  649.     ;;
  650.     -x)
  651.     EXPAND_NUMBERS=1;
  652.     ;;
  653.     -y)
  654.     TCPSYN="-y"
  655.     ;;
  656.  
  657.     --version)
  658.     echo "ipfwadm wrapper version 1.1"
  659.     exit 0
  660.     ;;
  661.  
  662.     *) barf Unexpected argument \`"$1"\'.
  663.     ;;
  664.     esac
  665.     shift
  666. done
  667.  
  668. # Variables to worry about:
  669. #  $CHAIN - actual chain to work on.
  670. # X$MASQ_MODE - set if -M given.
  671. # X$COMMAND - set if this is a simple command conversion.
  672. # X$TARGET - set for COMMAND of -A, -I, -D or -P (but see REDIR and MASQ).
  673. # X$LIST - set if they want a list.
  674. # X$NUMERIC - list with -n.
  675. # X$LIST_VERBOSE - list all info.
  676. # X$EXPAND_NUMBERS - list full numbers.
  677. # X$OPTIONS - miscellaneous easy-to-convert options.
  678. # X$SRC_OPTIONS - set if a source address is specified.
  679. # X$SRC_PORTS - space-separated list of specified source ports/ranges.
  680. # X$DST_OPTIONS - set if a dest address is specified.
  681. # X$DST_PORTS - space-separated list of specified dest ports/ranges.
  682. #  $VIA_ADDR - an interface address if one is specified.
  683. #  $INTERFACE - an interface name if one is specified.
  684. # X$TCPSYN - set if `-k' or `-y' is specified.
  685. # X$MASQ - set if `-m' is specified.
  686. # X$REDIR - set to the port if `-r port' is specified
  687.  
  688. if [ -n "$MASQ_MODE" ]
  689. then
  690.     if [ -n "$LIST" ]
  691.     then
  692.     $IPCHAINS -M -L $OPTIONS
  693.     else
  694.     $IPCHAINS $COMMAND $OPTIONS
  695.     fi
  696. elif [ -n "$LIST" ]
  697. then
  698.     if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES
  699.     then
  700.     echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2
  701.     exit 0
  702.     fi
  703.     # Construct a list.
  704.     if [ x$COMMAND = x-Z ]
  705.     then
  706.     # We have to atomically zero and list a chain.  This is
  707.     # currently impossible, so we:
  708.     # 1) stop all packets on the given chain. 
  709.     # 2) list the values.
  710.     # 3) clear the counters.
  711.     # 4) resume on the given chain.
  712.     case "$CHAIN" in
  713.         acct*)
  714.         $IPCHAINS -I 1 input -j DENY
  715.         $IPCHAINS -I 1 output -j DENY
  716.         ;;
  717.         inp)
  718.         $IPCHAINS -I 1 input -j DENY
  719.         ;;
  720.         out)
  721.         $IPCHAINS -I 1 output -j DENY
  722.         ;;
  723.         fwd)
  724.         $IPCHAINS -I 1 forward -j DENY
  725.         ;;
  726.         *) barf Unknown chain to stop: \`"$CHAIN"\'.
  727.     esac
  728.  
  729.     list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS"
  730.     $IPFWADM -Z $CHAIN
  731.     
  732.     case "$CHAIN" in
  733.         acct*)
  734.         $IPCHAINS -D 1 input
  735.         $IPCHAINS -D 1 output
  736.         ;;
  737.         inp)
  738.         $IPCHAINS -D 1 input
  739.         ;;
  740.         out)
  741.         $IPCHAINS -D 1 output
  742.         ;;
  743.         fwd)
  744.         $IPCHAINS -D 1 forward
  745.         ;;
  746.         *) barf Unknown chain to restart: \`"$CHAIN"\'.
  747.     esac
  748.     else
  749.     list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS"
  750.     fi
  751. elif [ x"$COMMAND" = x"-F" -o x"$COMMAND" = x"-Z" -o x"$COMMAND" = x"-C" ]
  752. then
  753.     if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES
  754.     then
  755.     echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2
  756.     exit 0
  757.     fi
  758.     if [ "$CHAIN" = acctboth ]
  759.     then
  760.     # Do it to all of them.
  761.     $IPCHAINS $COMMAND acctin $OPTIONS
  762.     $IPCHAINS $COMMAND acctout $OPTIONS
  763.     fi
  764.     $IPCHAINS $COMMAND $CHAIN $OPTIONS
  765. else
  766.     grep -q IpFwAdM! < $PROC_FIREWALL_NAMES || setup_chains
  767.  
  768.     # Figure out what the target should be.
  769.     if [ -n "$REDIR" ]
  770.     then
  771.     TARGET=REDIRECT
  772.     elif [ -n "$MASQ" ]
  773.     then
  774.     TARGET=MASQ
  775.     fi
  776.  
  777.     if [ x"$COMMAND" = x"-P" ]
  778.     then
  779.     case "$CHAIN" in
  780.     inp) CHAIN=input ;;
  781.     out) CHAIN=output ;;
  782.     fwd) CHAIN=forward ;;
  783.     *) barf "Illegal chain for -P: \`$CHAIN'" ;;
  784.     esac
  785.     $IPCHAINS $COMMAND $CHAIN $TARGET $OPTIONS
  786.     else
  787.     # If they used -V, and not -W, then try to figure out interface
  788.     # name.  ALWAYS warn about difference.
  789.     if [ -n "$VIA_ADDR" ]
  790.     then
  791.         if [ -n "$INTERFACE" ]
  792.         then
  793.         echo Warning: \`-V $VIA_ADDR\' option ignored\; using \`-W $INTERFACE\' only.
  794.         else
  795.         INTERFACE=`ifconfig | awk -v ADDR=$VIA_ADDR '/^[a-z0-9A-Z]/ { IFNAME=$1 } $0 ~ "^[^A-Za-z0-9:]*inet addr:" ADDR { print IFNAME}'`
  796.         if [ -z "$INTERFACE" ]
  797.         then
  798.             echo Can\'t handle -V option: can\'t find interface name for the address \`$VIA_ADDR\'. 1>&2
  799.             echo Please replace the -V with the appropriate -W option. 1>&2
  800.             exit 1
  801.         fi
  802.         echo Replacing \`-V $VIA_ADDR\' with \`-W $INTERFACE\'.
  803.         OPTIONS="$OPTIONS -i $INTERFACE"
  804.         fi
  805.     fi
  806.  
  807.     # Insert, append or delete.
  808.     case $COMMAND in
  809.         # For Insert, get (and decrement) minimal mark #.
  810.         -I*) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -3 | tail -1); echo $9)
  811.         $IPCHAINS -R $SPECIAL_CHAIN 1 -m $(($MARK - 1))
  812.         MARK="-m $MARK"
  813.         ;;
  814.  
  815.         # For Append, get (and increment) maximum mark #.
  816.         -A) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -4 | tail -1); echo $9)
  817.         $IPCHAINS -R $SPECIAL_CHAIN 2 -m $(($MARK + 1))
  818.         MARK="-m $MARK"
  819.         ;;
  820.     esac
  821.  
  822.     # Only care about TCP SYN if -p TCP not specified.
  823.     if [ -n "$TCPSYN" ]
  824.     then
  825.         case "$PROTOCOL" in
  826.         *[Tt][Cc][Pp]) 
  827.             OPTIONS="$OPTIONS $PROTOCOL $TCPSYN"
  828.             TCPSYN=""
  829.         ;;
  830.         esac
  831.     else
  832.         OPTIONS="$OPTIONS $PROTOCOL"
  833.     fi
  834.  
  835.     # Mangle source port and dest port args.
  836.     if [ -z "$SRC_PORTS" ]; then SRC_PORTS="X"; fi
  837.     if [ -z "$DST_PORTS" ]; then DST_PORTS="X"; fi
  838.  
  839.     [ -n "$TARGET" ] && TARGET="-j $TARGET"
  840.     for SRC in $SRC_PORTS
  841.     do
  842.         if [ $SRC = "X" ]; then SRC=""; fi
  843.         for DST in $DST_PORTS
  844.         do
  845.         if [ $DST = "X" ]; then DST=""; fi
  846.         if [ -n "$TCPSYN" ]
  847.         then
  848.             $IPCHAINS $COMMAND $CHAIN $SRC $DST $OPTIONS -p ! tcp $TARGET $MARK || barf "ipchains failed!"
  849.             $IPCHAINS $COMMAND $CHAIN $SRC $DST $OPTIONS -p tcp $TCPSYN $TARGET $MARK  || barf "ipchains failed!"
  850.         else
  851.             $IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS $TARGET $MARK
  852.         fi
  853.         done
  854.     done
  855.     fi
  856. fi
  857.